package rediscli

import (
	"fmt"
	"github.com/astaxie/beego"
	"github.com/go-redis/redis/v8"
	"gitlab.vrviu.com/inviu/backend-go-public/gopublic/otelwrap"
	"golang.org/x/net/context"
	"strings"
	"sync"
	"time"
)

var (
	// RedisClient - 通用客户端
	_client         redis.UniversalClient
	_OnceInitClient sync.Once
)

func TestBeego() {
	fmt.Printf("%s", beego.AppConfig.String("redis::hosts"))
	fmt.Printf("%s", beego.AppConfig.DefaultString("redis::username", ""))
	fmt.Printf("%s", beego.AppConfig.DefaultString("redis::password", ""))
}
func initClient() {
	_client = redis.NewUniversalClient(&redis.UniversalOptions{
		Addrs:            strings.Split(beego.AppConfig.String("redis::hosts"), ","),
		Username:         beego.AppConfig.DefaultString("redis::username", ""),
		Password:         beego.AppConfig.DefaultString("redis::password", ""),
		ReadTimeout:      time.Duration(beego.AppConfig.DefaultInt("redis::read_timeout", 300)) * time.Millisecond,
		WriteTimeout:     time.Duration(beego.AppConfig.DefaultInt("redis::write_timeout", 300)) * time.Millisecond,
		PoolSize:         beego.AppConfig.DefaultInt("redis::conn_pool_capacity", 0),
		IdleTimeout:      time.Duration(beego.AppConfig.DefaultInt("redis::conn_pool_idle_timeout", 240)) * time.Second,
		MasterName:       beego.AppConfig.DefaultString("redis::mastername", ""),
		SentinelPassword: beego.AppConfig.DefaultString("redis::sentinel_password", ""),
	})
	if beego.AppConfig.DefaultBool("redis::enable_otel", false) {
		_client.AddHook(NewTracingHook())
	}
	// rdb.HMSet()
}

// GetRedisCli -
func GetRedisCli(clients ...redis.UniversalClient) redis.UniversalClient {
	if len(clients) != 0 && clients[0] != nil {
		return clients[0]
	}

	if _client == nil {
		_OnceInitClient.Do(func() {
			initClient()
		})
	}
	return _client
}

// WriteDataToRedis 插入redis 数据
func WriteDataToRedis(ctx context.Context, key string, value interface{}, clients ...redis.UniversalClient) error {
	_, err := GetRedisCli(clients...).Set(ctx, key, value, 0).Result()
	return err
}

func RedisGetStringWithCtx(ctx context.Context, key string, clients ...redis.UniversalClient) (string, error) {
	get := GetRedisCli(clients...).Get(ctx, key)
	return get.Result()
}

func RedisGetWithCtx(ctx context.Context, key string, value interface{}, clients ...redis.UniversalClient) error {
	get := GetRedisCli(clients...).Get(ctx, key)
	return get.Scan(value)
}
func RedisGetIntWithCtx(ctx context.Context, key string, clients ...redis.UniversalClient) (int, error) {
	get := GetRedisCli(clients...).Get(ctx, key)
	return get.Int()
}

// RedisHGetString 获取哈希指定域的值（字符串）
// @param   key: 键
// @param field: 域
func RedisHGetString(key, field string, clients ...redis.UniversalClient) (string, error) {
	return RedisHGetStringWithCtx(otelwrap.Skip(), key, field, clients...)
}
func RedisHGetStringWithCtx(ctx context.Context, key, field string, clients ...redis.UniversalClient) (string, error) {
	hget := GetRedisCli(clients...).HGet(ctx, key, field)
	return hget.Result()
}

// RedisHGetInt 获取哈希指定域的值（字符串）
// @param   key: 键
// @param field: 域
func RedisHGetInt(key, field string, clients ...redis.UniversalClient) (int, error) {
	return RedisHGetIntWithCtx(otelwrap.Skip(), key, field, clients...)
}

func RedisHGetIntWithCtx(ctx context.Context, key, field string, clients ...redis.UniversalClient) (int, error) {
	hget := GetRedisCli(clients...).HGet(ctx, key, field)
	return hget.Int()
}

// RedisHMGet 批量获取哈希指定域的值
// @param   key: 键
// @param field: 域
// @return <arg_1>: 值列表，类型为string或nil
func RedisHMGet(key string, field []string, clients ...redis.UniversalClient) ([]interface{}, error) {
	return RedisHMGetWithCtx(otelwrap.Skip(), key, field, clients...)
}

func RedisHMGetWithCtx(ctx context.Context, key string, field []string, clients ...redis.UniversalClient) ([]interface{}, error) {
	return GetRedisCli(clients...).HMGet(ctx, key, field...).Result()
}
